#pragma once
#include <iostream>
#include <assert.h>
#include <thread>
using namespace std;
class FreeList
{
public:
    void Push(void *obj)
    {
        *(void **)obj = _list_head;
        _list_head = obj;
    }
    void *Pop()
    {
        void *obj = _list_head;
        _list_head = *(void **)obj;
        return obj;
    }
    bool Empty()
    {
        return _list_head == nullptr;
    }
private:
    void *_list_head = nullptr;
};
class SizeClass
{
    // 整体控制在最多10%左右的内碎片浪费
    // [1,128]					8byte对齐	     freelist[0,16)
    // [128+1,1024]				16byte对齐	     freelist[16,72)
    // [1024+1,8*1024]			128byte对齐	     freelist[72,128)
    // [8*1024+1,64*1024]		1024byte对齐     freelist[128,184)
    // [64*1024+1,256*1024]		8*1024byte对齐   freelist[184,208)
public:
    // int _RoundUP(size_t size, size_t alignNum)
    // {
    //     if (size % alignNum == 0)
    //         return size;
    //     else
    //         return (size / alignNum + 1) * alignNum;
    // }
    static inline int _RoundUP(size_t bytes, size_t alignNum)
    {
        return (bytes + alignNum - 1) & ~(alignNum - 1);
    }
    static inline int RoundUP(size_t bytes)
    {
        if (bytes <= 128)
            return _RoundUP(bytes, 8);
        else if (bytes <= 1024)
            return _RoundUP(bytes, 16);
        else if (bytes <= 8 * 1024)
            return _RoundUP(bytes, 128);
        else if (bytes <= 64 * 1024)
            return _RoundUP(bytes, 1024);
        else if (bytes <= 256 * 1024)
            return _RoundUP(bytes, 8 * 1024);
        else
        {
            assert(false);
            return 1;
        }
    }
    static inline int _Index(size_t bytes, size_t align_shift)
    {
        return ((bytes + (1 << align_shift) - 1) >> align_shift) - 1;
    }
    static inline int Index(size_t bytes)
    {
        if (bytes <= 128)
            return _Index(bytes, 3);
        else if (bytes <= 1024)
            return _Index(bytes, 4);
        else if (bytes <= 8 * 1024)
            return _Index(bytes, 7);
        else if (bytes <= 64 * 1024)
            return _Index(bytes, 10);
        else if (bytes <= 256 * 1024)
            return _Index(bytes, 13);
        else
        {
            assert(false);
            return 1;
        }
    }

private:
};